package com.fizzgate.dynamic.event.handle;

import com.alipay.sofa.ark.spi.event.biz.BeforeBizStopEvent;
import com.alipay.sofa.ark.spi.model.Biz;
import com.alipay.sofa.ark.spi.service.event.EventHandler;
import com.alipay.sofa.serverless.common.api.SpringServiceFinder;
import com.fizzgate.dynamic.util.NodeBizUtils;
import com.fizzgate.plugin.FizzPluginFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Map;
@Component
public class NodeBeforeBizStopEventHandle implements EventHandler<BeforeBizStopEvent> {
    @Resource
    private ReactiveWebServerApplicationContext applicationContext;
    private static final Logger LOGGER = LoggerFactory.getLogger(NodeBeforeBizStopEventHandle.class);

    private void unLoadPlugin(Biz biz) {
        Map<String, FizzPluginFilter> filters = SpringServiceFinder.listModuleServices(biz.getBizName(), biz.getBizVersion(), FizzPluginFilter.class);
        filters.forEach((name, pluginFilter)-> {
            BizFilterPluginCache.remove(name);
            FizzPluginFilter dynamicPluginFilter = null;
            try{

                dynamicPluginFilter =  (FizzPluginFilter)applicationContext.getBean(name);
            }catch (NoSuchBeanDefinitionException e){
                // do nothing
            }
            // 动态加载插件
            if (dynamicPluginFilter != null){
                LOGGER.info("find dynamic id:{}, prepare to remove it", name);
                DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)applicationContext.getBeanFactory();
                beanFactory.destroySingleton(name);
            }
        });
    }

    @Override
    public void handleEvent(BeforeBizStopEvent event) {
        Biz biz = event.getSource();
        if (NodeBizUtils.isArkBiz(biz)){
            try {
                unLoadPlugin(biz);
            } catch (IllegalStateException e) {
                e.printStackTrace();
                LOGGER.error("unload plugin id:{}:{}, get error:{}",biz.getBizName(),biz.getBizVersion(),e.getMessage());
            }
        }
        LOGGER.info("handle stop event of biz: {}", biz.getBizName());
    }

    @Override
    public int getPriority() {
        return 0;
    }
}
